/*
 * @Author: 飞越疯人院 353362604@qq.com
 * @Date: 2022-05-24 17:12:37
 * @LastEditors: 飞越疯人院 353362604@qq.com
 * @LastEditTime: 2022-11-25 09:51:22
 * @FilePath: \reconfiguration-administration\src\Common\Mars3D\RightBox.jsx
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */

import { Http } from '../Api'
import { project } from '../Data'
import { KMLData } from './Mars3Config'
import { TilesEditor } from './TilesEditor'
import { useState, useEffect } from 'react'
import { FormItemModal, ClickFromModal } from './Form'
import { DrawElement, ModifyElement } from './DrawElement'
import { CloseOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons'
import { useBoolean, useEventEmitter, useSetState, useRequest, useLatest, useLocalStorageState } from 'ahooks'
import { KMLFormData, ModelFormData, ElementFormData, ElementStyleData, moveImg, rotateImg } from './Mars3Config'
import {
    Form,
    Select,
    Button,
    message,
    Switch,
    Tabs,
    InputNumber,
    Slider,
    Result,
    Modal,
    List,
    Card,
    Popconfirm,
} from 'antd'

const { imageUrl } = project[window.location.hostname]
const { Option } = Select
const { mars3d, Cesium } = window
const styleList = { 0: '自定义事件', 1: '智能机器人' }
const targetList = { 0: '模型', 1: '进度', 2: '监控', 3: '数据', 4: '全景' }

/**
 *
 * !!! KML
 *
 */

// 添加KML
export const AddKML = ({ off, Map, newModelEvent, ScenesUuid }) => {
    const parameter = KMLFormData.add
    const [form] = Form.useForm()
    const [disabled, { setTrue, setFalse }] = useBoolean(false)
    const [KMLSelect, setKMLSelect] = useState({})
    const [KMLDetails, setKMLDetails] = useState()
    const KMLLoad = () => {
        const { url } = KMLSelect
        if (!url) {
            message.error('请先选择需要加载的KML!')
            return false
        }
        setTrue()
        const kml = new mars3d.layer.KmlLayer({
            url: url,
            symbol: ElementStyleData['kmlList'].type()['KML001'].style,
            flyTo: true,
        })
        setKMLDetails(kml)
        Map.addLayer(kml)
    }
    const StyleSelectEvent = useEventEmitter()
    StyleSelectEvent.useSubscription(val => {
        KMLDetails.clear()
        const kml = new mars3d.layer.KmlLayer({
            url: KMLSelect.url,
            symbol: ElementStyleData['kmlList'].type()[val].style,
        })
        setKMLDetails(kml)
        Map.addLayer(kml)
    })
    const Reset = () => {
        KMLDetails.clear()
        setFalse()
    }
    // 创建元素
    const { run: posElements } = useRequest(Http, {
        manual: true,
        onSuccess: ({ sortId, isEnabled, tableName, uuid }) => {
            const data = { sortId, isEnabled, tableName, category: 'Elements', constitutesUuid: uuid, ScenesUuid }
            posScenesDetails({ url: `posScenesDetails`, data })
        },
    })
    // 添加场景明细
    const { run: posScenesDetails } = useRequest(Http, {
        manual: true,
        onSuccess: () => {
            message.success('KML创建成功!')
            newModelEvent.emit()
            off()
        },
    })

    const ColorEvent = useEventEmitter()
    ColorEvent.useSubscription(val => {
        let style = KMLDetails.options.symbol
        style.styleOptions.color = val
        KMLDetails.updateStyle(style)
    })

    return (
        <div className="ModelBox animate__animated  animate__slideInRight">
            <div className="ModelBoxClose" onClick={off}>
                <div>新增KML</div>
                <CloseOutlined />
            </div>
            <div className="SingleLine">
                <div>路径 : </div>
                <div>
                    <Select
                        style={{ width: '100%' }}
                        disabled={disabled}
                        onChange={e => {
                            setKMLSelect({ uuid: e, url: `${imageUrl}${KMLData.find(v => v.uuid === e).url}` })
                        }}
                    >
                        {KMLData &&
                            KMLData.map(item => (
                                <Option key={item.uuid} value={item.uuid}>
                                    {item.tableName}
                                </Option>
                            ))}
                    </Select>
                </div>
            </div>
            <div className="options">
                {disabled ? (
                    <Button onClick={Reset}>重新选择</Button>
                ) : (
                    <Button onClick={KMLLoad} type="primary">
                        加载KML
                    </Button>
                )}
            </div>
            {disabled && (
                <>
                    <Form
                        className="scenesBase"
                        form={form}
                        layout="vertical"
                        onFinish={data => {
                            data.center = JSON.stringify(data.center)
                            data.storageType = 1
                            data.storagePath = KMLSelect.url
                            posElements({ url: `posElements`, data })
                        }}
                    >
                        <FormItemModal
                            Map={Map}
                            form={form}
                            data={parameter}
                            ModelUrlEvent={StyleSelectEvent}
                            ColorEvent={ColorEvent}
                        />
                    </Form>
                    <div className="options">
                        <Button block type="primary" onClick={() => form.submit()}>
                            保存数据
                        </Button>
                    </div>
                </>
            )}
        </div>
    )
}

// 修改KML
export const ModKML = ({ off, Map, newModelEvent, ScenesUuid, KMLModifyData }) => {
    const parameter = KMLFormData.modify
    const [form] = Form.useForm()
    const [KMLDetails, setKMLDetails] = useState()

    useEffect(() => {
        setKMLDetails(Map.getLayerById(KMLModifyData.elementUuid))
        form.setFieldsValue(KMLModifyData)
    }, [KMLModifyData, Map, form])
    const StyleSelectEvent = useEventEmitter()

    StyleSelectEvent.useSubscription(val => {
        KMLDetails.clear()
        const kml = new mars3d.layer.KmlLayer({
            url: KMLModifyData.storagePath,
            symbol: ElementStyleData['kmlList'].type()[val].style,
        })
        setKMLDetails(kml)
        Map.addLayer(kml)
    })

    const { run: putElement } = useRequest(Http, {
        manual: true,
        onSuccess: (_, res) => {
            const { sortId, isEnabled, tableName, uuid } = res[0].data
            const data = {
                sortId,
                isEnabled,
                tableName,
                category: 'Elements',
                constitutesUuid: uuid,
                ScenesUuid,
                uuid: KMLModifyData.scenesDetailsUuid,
            }
            putScenesDetails({ url: `putScenesDetails`, data, path: [KMLModifyData.scenesDetailsUuid] })
        },
    })
    const { run: putScenesDetails } = useRequest(Http, {
        manual: true,
        onSuccess: () => {
            message.success('KML修改成功!')
            newModelEvent.emit()
            off()
        },
    })

    const ColorEvent = useEventEmitter()
    ColorEvent.useSubscription(val => {
        let style = KMLDetails.options.symbol
        style.styleOptions.color = val
        KMLDetails.updateStyle(style)
    })

    return (
        <div className="ModelBox animate__animated  animate__slideInRight">
            <div className="ModelBoxClose" onClick={off}>
                <div>修改KML</div>
                <CloseOutlined />
            </div>
            <Form
                className="scenesBase"
                form={form}
                layout="vertical"
                onFinish={data => {
                    data.storageType = 1
                    data.center = JSON.stringify(data.center)
                    data.uuid = KMLModifyData.elementUuid
                    putElement({ url: `putElements`, data, path: [KMLModifyData.elementUuid] })
                }}
            >
                <FormItemModal
                    Map={Map}
                    form={form}
                    data={parameter}
                    ModelUrlEvent={StyleSelectEvent}
                    ColorEvent={ColorEvent}
                />
            </Form>
            <div className="options">
                <Button block type="primary" onClick={() => form.submit()}>
                    保存数据
                </Button>
            </div>
        </div>
    )
}

/**
 *
 * !!! 元素
 *
 */
// 添加修改元素
export const ElementForm = ({ off, Map, Gra, newModelEvent, ScenesUuid, EleModifyData }) => {
    const parameter = ElementFormData
    const [form] = Form.useForm()
    const [CenterData, setCenterData] = useState({})
    // 新增元素
    // 添加场景明细
    const { runAsync: posScenesDetails } = useRequest(Http, { manual: true })
    const { run: posElements } = useRequest(Http, {
        manual: true,
        onSuccess: ({ uuid, tableName, sortId, isEnabled }) => {
            const data = { sortId, isEnabled, tableName, category: 'Elements', constitutesUuid: uuid, ScenesUuid }
            posScenesDetails({ url: `posScenesDetails`, data }).then(() => {
                message.success('场景明细创建成功!')
                newModelEvent.emit()
                off()
            })
        },
    })
    // 修改元素
    // 修改场景明细
    const { runAsync: putScenesDetails } = useRequest(Http, { manual: true })
    const { run: putElements } = useRequest(Http, {
        manual: true,
        onSuccess: (_, res) => {
            const { sortId, isEnabled, tableName, uuid } = res[0].data
            const data = {
                sortId,
                isEnabled,
                tableName,
                category: 'Elements',
                constitutesUuid: uuid,
                ScenesUuid,
                uuid: EleModifyData.uuid,
            }
            putScenesDetails({ url: `putScenesDetails`, data, path: [EleModifyData.uuid] }).then(() => {
                message.success('场景明细修改成功!')
                newModelEvent.emit()
                off()
            })
        },
    })
    useEffect(() => {
        if (JSON.stringify(EleModifyData) !== '{}') {
            EleModifyData.center =
                typeof EleModifyData.center === 'string' ? JSON.parse(EleModifyData.center) : EleModifyData.center
            form.setFieldsValue({ ...EleModifyData, uuid: EleModifyData.elementUuid })
            setCenterData({ center: EleModifyData.center, icon: EleModifyData.icon })
        }
    }, [EleModifyData, form])

    return (
        <div className="ModelBox animate__animated  animate__slideInRight">
            <div className="ModelBoxClose" onClick={off}>
                <div>元素操作</div>
                <CloseOutlined />
            </div>
            <Form
                className="scenesBase"
                form={form}
                layout="vertical"
                onFinish={data => {
                    data.center = JSON.stringify(data.center)
                    data.storageType = 0
                    Gra.clear()
                    if (data.uuid) putElements({ url: `putElements`, data, path: [data.uuid] })
                    else posElements({ url: `posElements`, data })
                }}
            >
                <FormItemModal Map={Map} data={parameter} form={form} baseData={CenterData} />
            </Form>
            <div className="options">
                <Button block type="primary" onClick={() => form.submit()}>
                    保存数据
                </Button>
            </div>
        </div>
    )
}

// 添加修改元素明细
export const ElementDetailForm = ({ off, Map, Gra, newModelEvent, EleModifyData, DetModifyData }) => {
    const [state, { setTrue, setFalse }] = useBoolean(false)
    const ElementDetailsEvent = useEventEmitter()
    useEffect(() => {
        if (JSON.stringify(DetModifyData) === '{}') setTrue()
        else setFalse()
    }, [DetModifyData, setFalse, setTrue])

    ElementDetailsEvent.useSubscription(val => {
        const { type, data } = val
        delete data.icon
        switch (type) {
            case 'add':
                return posElementsDetails({ url: `posElementDetails`, data })
            case 'modify':
                return putElementsDetails({ url: `putElementDetails`, data, path: [data.uuid] })
            case 'state':
                return console.log('修改明细状态')
            default:
                break
        }
    })

    // 新增元素明细
    const { run: posElementsDetails } = useRequest(Http, {
        manual: true,
        onSuccess: () => {
            message.success('新增元素明细成功')
            newModelEvent.emit()
            off()
        },
    })
    // 修改元素明细
    const { run: putElementsDetails } = useRequest(Http, {
        manual: true,
        onSuccess: () => {
            message.success('修改元素明细成功')
            newModelEvent.emit()
            off()
        },
    })
    return (
        <div className="ModelBox animate__animated  animate__slideInRight">
            <div className="ModelBoxClose" onClick={off}>
                <div>
                    {state ? '新增' : '修改'} {ElementStyleData[EleModifyData.elementType].name} 明细元素操作
                </div>
                <CloseOutlined />
            </div>
            {state ? (
                <DrawElement Map={Map} Elements={EleModifyData} ElementDetailsEvent={ElementDetailsEvent} />
            ) : (
                <ModifyElement
                    Map={Map}
                    Gra={Gra}
                    Elements={EleModifyData}
                    ElementDetails={DetModifyData}
                    ElementDetailsEvent={ElementDetailsEvent}
                />
            )}
        </div>
    )
}

/**
 *
 * !!! 模型
 *
 */
// 添加模型
export const AddMod = ({ off, Map, newModelEvent, ScenesUuid }) => {
    const [ClientData] = useLocalStorageState('ClientData')
    const [disabled, { setTrue, setFalse }] = useBoolean(false)
    const [tiles3dLayer, setTiles3dLayer] = useState()
    const tiles3dLayerLate = useLatest(tiles3dLayer)
    const [ModelData, setModelData] = useSetState({
        url: '',
        uuid: '',
        lng: 0,
        lat: 0,
        alt: 0,
        x: 0,
        y: 0,
        z: 0,
        scale: 1,
        opacity: 0,
    })
    const ModelDataLast = useLatest(ModelData)
    const [ModelList, setModelList] = useState([])
    const [form] = Form.useForm()
    // 模型拖拽
    const [Editor] = useState(new TilesEditor({ map: Map, moveImg, rotateImg }))
    Editor.on('change', data => ModifyEditor(data))
    useEffect(() => {
        return () => Editor.off('change')
    }, [Editor])
    const { run: ModifyEditor } = useRequest(async data => new Promise(resolve => resolve(data)), {
        throttleWait: 100,
        manual: true,
        onSuccess: data => {
            if (Cesium.defined(data.position)) {
                const pos = data.position
                const thisZ = ModelDataLast.current.alt
                const position = mars3d.PointUtil.setPositionsHeight(pos, thisZ)
                const point = mars3d.LngLatPoint.fromCartesian(position)
                Editor.position = position
                tiles3dLayerLate.current.center = point
                const { lng, lat, alt } = point
                ModelDataLast.current.lng = Number(lng)
                ModelDataLast.current.lat = Number(lat)
                ModelDataLast.current.alt = Number(alt)
                setModelData(ModelDataLast.current)
                setTiles3dLayer(tiles3dLayerLate.current)
            } else if (Cesium.defined(data.heading)) {
                tiles3dLayerLate.current.rotation_z = data.heading
                const { rotation_z } = tiles3dLayerLate.current
                setModelData((ModelDataLast.current.z = Number(rotation_z)))
                setTiles3dLayer(tiles3dLayerLate.current)
            }
        },
    })
    // 模型与input同步
    useEffect(() => {
        const { lng, lat, alt, x, y, z, scale, opacity } = ModelData
        const position = { lng, lat, alt }
        const rotation = { x, y, z }
        if (tiles3dLayer && tiles3dLayer._state !== 'destroy') {
            tiles3dLayer.setOptions({ position, rotation, scale })
            tiles3dLayer.setOpacity(opacity)
            Editor.heading = tiles3dLayer.rotation_z
            Editor.position = tiles3dLayer.position
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [ModelData])
    // 卸载模型
    useEffect(() => {
        return () => {
            if (tiles3dLayerLate.current) {
                tiles3dLayerLate.current.remove(true)
                Editor.enabled = false
            }
        }
    }, [Editor, tiles3dLayerLate])
    // 获取模型列表
    const { run: getFileUris } = useRequest(Http, { manual: true, onSuccess: ({ list }) => setModelList(list) })
    useEffect(() => {
        const [key] = Object.keys(ClientData.project)
        getFileUris({ url: `getFiles`, data: { fileType: '3DTiles', projectUuid: key } })
    }, [getFileUris, ClientData])
    // 跳转模型
    const flyModel = () => {
        if (tiles3dLayer.tileset?.boundingSphere)
            Map.camera.flyToBoundingSphere(tiles3dLayer.tileset.boundingSphere, {
                offset: new Cesium.HeadingPitchRange(
                    Map.camera.heading,
                    Map.camera.pitch,
                    tiles3dLayer.tileset.boundingSphere.radius * 2,
                ),
            })
        else Map.flyToPoint(tiles3dLayer.position, { radius: tiles3dLayer.tileset.boundingSphere.radius * 2 })
    }
    // 加载模型
    const loadModel = type => {
        const { url } = ModelData
        if (!url) {
            message.error('请选择需要加载的模型!')
            return false
        }
        const { lng, lat, alt } = Map.getCenter()
        let TilesetLayerObject = { url: url, flyTo: true }
        if (type === 0) TilesetLayerObject.position = { lng, lat, alt }
        const Model = new mars3d.layer.TilesetLayer(TilesetLayerObject)
        Map.addLayer(Model)
        Model.on(mars3d.EventType.load, e => {
            const data = e.tileset
            if (Model.transform) {
                Editor.range = data.boundingSphere.radius * 0.9
                Editor.heading = Model.rotation_z
                Editor.position = Model.position
            } else Editor.enabled = false

            const { center, opacity, orginRotation, scale } = Model
            setModelData({
                lng: center._lng,
                lat: center._lat,
                alt: center._alt,
                x: orginRotation.x,
                y: orginRotation.y,
                z: orginRotation.z,
                scale,
                opacity,
            })
            setTrue()
        })
        setTiles3dLayer((tiles3dLayerLate.current = Model))
    }
    // 模型明细数据
    const parameter = ModelFormData.add
    // 保存模型数据
    const { runAsync: posScenesDetails } = useRequest(Http, { manual: true })
    const saveModelData = e => {
        const { tableName, center, isEnabled, sortId } = e
        const { lng, lat, alt, uuid, url, x, y, z, scale, opacity } = ModelData
        const data = {
            ScenesUuid,
            tableName,
            center: JSON.stringify(center),
            isEnabled,
            sortId,
            category: 'Files',
            longitude: lng,
            latitude: lat,
            altitude: alt,
            constitutesUuid: uuid,
            storagePath: url,
            rotate: JSON.stringify({ x, y, z }),
            scale,
            opacity,
        }
        posScenesDetails({ url: `posScenesDetails`, data }).then(() => {
            Editor.enabled = false
            message.success('模型添加成功')
            off()
            newModelEvent.emit()
        })
    }

    const TabsItem = [
        {
            label: '明细数据',
            key: '1',
            children: (
                <Form className="scenesBase" form={form} layout="vertical" onFinish={saveModelData}>
                    <FormItemModal Map={Map} form={form} data={parameter} />
                </Form>
            ),
        },
        {
            label: '模型数据',
            key: '2',
            children: (
                <>
                    <div className="SingleLine">
                        <div>经度 : </div>
                        <div>
                            <InputNumber
                                stringMode
                                min={-180}
                                max={180}
                                step={0.000001}
                                value={ModelData.lng}
                                placeholder="请输入模型经度"
                                onChange={e => setModelData((ModelDataLast.current.lng = Number(e)))}
                            />
                        </div>
                    </div>
                    <div className="SingleLine">
                        <div>纬度 : </div>
                        <div>
                            <InputNumber
                                stringMode
                                min={-180}
                                max={180}
                                step={0.000001}
                                value={ModelData.lat}
                                placeholder="请输入模型纬度"
                                onChange={e => setModelData((ModelDataLast.current.lat = Number(e)))}
                            />
                        </div>
                    </div>
                    <div className="SingleLine">
                        <div>高程 : </div>
                        <div>
                            <InputNumber
                                stringMode
                                step={0.1}
                                value={ModelData.alt}
                                placeholder="请输入模型高程"
                                onChange={e => setModelData((ModelDataLast.current.alt = Number(e)))}
                            />
                        </div>
                    </div>
                    <div className="SingleLine">
                        <div>X方向 : </div>
                        <div>
                            <InputNumber
                                stringMode
                                min={-360}
                                max={360}
                                step={0.0001}
                                value={ModelData.x}
                                placeholder="请输入模型X方向"
                                onChange={e => setModelData((ModelDataLast.current.x = Number(e)))}
                            />
                        </div>
                    </div>
                    <div className="SingleLine">
                        <div>Y方向 : </div>
                        <div>
                            <InputNumber
                                stringMode
                                min={-360}
                                max={360}
                                step={0.0001}
                                value={ModelData.y}
                                placeholder="请输入模型Y方向"
                                onChange={e => setModelData((ModelDataLast.current.y = Number(e)))}
                            />
                        </div>
                    </div>
                    <div className="SingleLine">
                        <div>Z方向 : </div>
                        <div>
                            <InputNumber
                                stringMode
                                min={-360}
                                max={360}
                                step={0.0001}
                                value={ModelData.z}
                                placeholder="请输入模型Z方向"
                                onChange={e => setModelData((ModelDataLast.current.z = Number(e)))}
                            />
                        </div>
                    </div>
                    <div className="SingleLine">
                        <div>缩放 : </div>
                        <div>
                            <InputNumber
                                stringMode
                                min={0.1}
                                step={0.1}
                                value={ModelData.scale}
                                placeholder="请输入模型缩放"
                                onChange={e => setModelData((ModelDataLast.current.scale = Number(e)))}
                            />
                        </div>
                    </div>
                    <div className="SingleLine">
                        <div>透明度 : </div>
                        <div>
                            <Slider
                                min={0}
                                max={1}
                                step={0.1}
                                value={ModelData.opacity}
                                onChange={e => setModelData((ModelDataLast.current.opacity = Number(e)))}
                            />
                        </div>
                    </div>
                </>
            ),
        },
    ]

    return (
        <div className="ModelBox animate__animated  animate__slideInRight">
            <div className="ModelBoxClose" onClick={off}>
                <div>添加模型</div>
                <CloseOutlined />
            </div>
            <div className="SingleLine">
                <div>模型 : </div>
                <div>
                    <Select
                        style={{ width: '100%' }}
                        disabled={disabled}
                        onChange={e => {
                            setModelData({ uuid: e, url: `${imageUrl}${ModelList.find(v => v.uuid === e).url}` })
                        }}
                    >
                        {ModelList &&
                            ModelList.map(item => (
                                <Option key={item.uuid} value={item.uuid}>
                                    {item.tableName}
                                </Option>
                            ))}
                    </Select>
                </div>
            </div>
            <div className="options">
                {disabled ? (
                    <>
                        <Button
                            danger
                            ghost
                            onClick={() => {
                                tiles3dLayer.remove(true)
                                setFalse()
                            }}
                        >
                            重新选择
                        </Button>
                        <Button onClick={flyModel} ghost>
                            定位模型
                        </Button>
                    </>
                ) : (
                    <>
                        <Button type="primary" onClick={() => loadModel(0)}>
                            加载到当前视角
                        </Button>
                        <Button type="primary" onClick={() => loadModel(1)}>
                            加载到模型视角
                        </Button>
                    </>
                )}
            </div>
            {disabled && (
                <>
                    <div className="SingleLine" style={{ margin: '15px 0' }}>
                        <div>拖拽编辑 : </div>
                        <div>
                            <Switch
                                defaultChecked={Editor.enabled}
                                onChange={e => {
                                    Editor.enabled = e
                                }}
                            />
                        </div>
                    </div>
                    <Tabs defaultActiveKey="1" centered items={TabsItem} />
                    <div className="options">
                        <Button block type="primary" onClick={() => form.submit()}>
                            保存数据
                        </Button>
                    </div>
                </>
            )}
        </div>
    )
}

// 修改模型
export const ModMod = ({ off, Map, newModelEvent, ScenesUuid, ModelModifyData }) => {
    const [form] = Form.useForm()
    const [ModelData, setModelData] = useSetState({
        url: '',
        lng: 0,
        lat: 0,
        alt: 0,
        x: 0,
        y: 0,
        z: 0,
        scale: 1,
        opacity: 0,
    })
    const ModelDataLast = useLatest(ModelData)
    const [tiles3dLayer, setTiles3dLayer] = useState()
    const tiles3dLayerLate = useLatest(tiles3dLayer)
    const sceneData = ModelFormData.modify
    // 模型拖拽
    const [Editor] = useState(new TilesEditor({ map: Map, moveImg, rotateImg }))
    Editor.on('change', data => ModifyEditor(data))
    useEffect(() => {
        return () => Editor.off('change')
    }, [Editor])
    const { run: ModifyEditor } = useRequest(async data => new Promise(resolve => resolve(data)), {
        throttleWait: 100,
        manual: true,
        onSuccess: data => {
            if (Cesium.defined(data.position)) {
                const pos = data.position
                const thisZ = ModelDataLast.current.alt
                const position = mars3d.PointUtil.setPositionsHeight(pos, thisZ)
                const point = mars3d.LngLatPoint.fromCartesian(position)
                Editor.position = position
                tiles3dLayerLate.current.center = point
                const { lng, lat, alt } = point
                ModelDataLast.current.lng = Number(lng)
                ModelDataLast.current.lat = Number(lat)
                ModelDataLast.current.alt = Number(alt)
                setModelData(ModelDataLast.current)
                setTiles3dLayer(tiles3dLayerLate.current)
            } else if (Cesium.defined(data.heading)) {
                tiles3dLayerLate.current.rotation_z = data.heading
                const { rotation_z } = tiles3dLayerLate.current
                setModelData((ModelDataLast.current.z = Number(rotation_z)))
                setTiles3dLayer(tiles3dLayerLate.current)
            }
        },
    })

    const { runAsync: putScenesDetails } = useRequest(Http, { manual: true })
    const putModelData = e => {
        const { tableName, center, isEnabled, sortId } = e
        const { lng, lat, alt, uuid, url, x, y, z, scale, opacity } = ModelData
        const data = {
            ...e,
            ScenesUuid,
            category: 'Files',
            tableName,
            center: JSON.stringify(center),
            isEnabled,
            sortId,
            longitude: lng,
            latitude: lat,
            altitude: alt,
            constitutesUuid: uuid,
            storagePath: url,
            rotate: JSON.stringify({ x, y, z }),
            scale,
            opacity,
            uuid: e.scenesDetailsUuid,
        }
        putScenesDetails({ url: `putScenesDetails`, data, path: [e.scenesDetailsUuid] }).then(() => {
            Editor.enabled = false
            off()
            message.success('模型修改成功')
            newModelEvent.emit()
        })
    }
    // 模型与input同步
    useEffect(() => {
        const { lng, lat, alt, x, y, z, scale, opacity } = ModelData
        const position = { lng, lat, alt }
        const rotation = { x, y, z }
        if (tiles3dLayer && tiles3dLayer._state !== 'destroy') {
            tiles3dLayer.setOptions({ position, rotation, scale })
            tiles3dLayer.setOpacity(opacity)
            Editor.heading = tiles3dLayer.rotation_z
            Editor.position = tiles3dLayer.position
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [ModelData])

    useEffect(() => {
        let data = ModelModifyData
        form.setFieldsValue(data)
        const rotate = data.rotate
        data.x = rotate.x
        data.y = rotate.y
        data.z = rotate.z
        const layer = Map.getLayerById(data.scenesDetailsUuid)
        const { tileset, rotation_z, position } = layer
        if (layer.transform) {
            Editor.range = tileset.boundingSphere.radius * 0.9
            Editor.heading = rotation_z
            Editor.position = position
        } else Editor.enabled = false
        setTiles3dLayer((tiles3dLayerLate.current = layer))
        let model = {
            url: data.storagePath,
            lng: Number(data.longitude),
            lat: Number(data.latitude),
            alt: Number(data.altitude),
            x: data.x,
            y: data.y,
            z: data.z,
            scale: Number(data.scale),
            opacity: Number(data.opacity),
        }
        setModelData(model)
    }, [Editor, Map, ModelModifyData, form, setModelData, tiles3dLayerLate])

    useEffect(() => {
        return () => (Editor.enabled = false)
    }, [Editor])

    const TabsItems = [
        {
            label: '明细数据',
            key: '1',
            children: <FormItemModal Map={Map} form={form} data={sceneData} />,
        },
        {
            label: '模型数据',
            key: '2',
            children: (
                <>
                    <div className="SingleLine">
                        <div>经度 : </div>
                        <div>
                            <InputNumber
                                stringMode
                                min={-180}
                                max={180}
                                step={0.000001}
                                value={ModelData.lng}
                                placeholder="请输入模型经度"
                                onChange={e => setModelData((ModelDataLast.current.lng = Number(e)))}
                            />
                        </div>
                    </div>
                    <div className="SingleLine">
                        <div>纬度 : </div>
                        <div>
                            <InputNumber
                                stringMode
                                min={-180}
                                max={180}
                                step={0.000001}
                                value={ModelData.lat}
                                placeholder="请输入模型纬度"
                                onChange={e => setModelData((ModelDataLast.current.lat = Number(e)))}
                            />
                        </div>
                    </div>
                    <div className="SingleLine">
                        <div>高程 : </div>
                        <div>
                            <InputNumber
                                stringMode
                                step={0.1}
                                value={ModelData.alt}
                                placeholder="请输入模型高程"
                                onChange={e => setModelData((ModelDataLast.current.alt = Number(e)))}
                            />
                        </div>
                    </div>
                    <div className="SingleLine">
                        <div>X方向 : </div>
                        <div>
                            <InputNumber
                                stringMode
                                min={0}
                                max={360}
                                step={0.1}
                                value={ModelData.x}
                                placeholder="请输入模型X方向"
                                onChange={e => setModelData((ModelDataLast.current.x = Number(e)))}
                            />
                        </div>
                    </div>
                    <div className="SingleLine">
                        <div>Y方向 : </div>
                        <div>
                            <InputNumber
                                stringMode
                                min={0}
                                max={360}
                                step={0.1}
                                value={ModelData.y}
                                placeholder="请输入模型Y方向"
                                onChange={e => setModelData((ModelDataLast.current.y = Number(e)))}
                            />
                        </div>
                    </div>
                    <div className="SingleLine">
                        <div>Z方向 : </div>
                        <div>
                            <InputNumber
                                stringMode
                                min={0}
                                max={360}
                                step={0.1}
                                value={ModelData.z}
                                placeholder="请输入模型Z方向"
                                onChange={e => setModelData((ModelDataLast.current.z = Number(e)))}
                            />
                        </div>
                    </div>
                    <div className="SingleLine">
                        <div>缩放 : </div>
                        <div>
                            <InputNumber
                                stringMode
                                min={0.1}
                                step={0.1}
                                value={ModelData.scale}
                                placeholder="请输入模型缩放"
                                onChange={e => setModelData((ModelDataLast.current.scale = Number(e)))}
                            />
                        </div>
                    </div>
                    <div className="SingleLine">
                        <div>透明度 : </div>
                        <div>
                            <Slider
                                min={0}
                                max={1}
                                step={0.1}
                                value={ModelData.opacity}
                                onChange={e => setModelData((ModelDataLast.current.opacity = Number(e)))}
                            />
                        </div>
                    </div>
                </>
            ),
        },
    ]

    return (
        <div className="ModelBox animate__animated animate__slideInRight">
            <div className="ModelBoxClose" onClick={off}>
                <div>修改模型</div>
                <CloseOutlined />
            </div>
            <div className="SingleLine">
                <div>拖拽编辑 : </div>
                <div>
                    <Switch
                        defaultChecked={Editor.enabled}
                        onChange={e => {
                            Editor.enabled = e
                        }}
                    />
                </div>
            </div>
            <Form className="scenesBase" form={form} layout="vertical" onFinish={putModelData}>
                <Tabs defaultActiveKey="1" centered items={TabsItems} />
            </Form>
            <div className="options">
                <Button block type="primary" onClick={() => form.submit()}>
                    保存数据
                </Button>
            </div>
        </div>
    )
}

/**
 *
 * !!! 事件
 *
 */

export const FunctionList = ({ off, ClickData }) => {
    const { ConstitutesUuid, Category, tableName } = ClickData
    const [form] = Form.useForm()
    const [ListState, { setTrue: listTrue, setFalse: listFalse }] = useBoolean(false)
    const [modalState, { setTrue: modalTrue, setFalse: modalFalse }] = useBoolean(false)
    const [ClickList, setClickList] = useState([])

    const { runAsync: posClick } = useRequest(Http, { manual: true })
    const { runAsync: putClick } = useRequest(Http, { manual: true })
    const { runAsync: delClick } = useRequest(Http, { manual: true })
    const { runAsync: getScene } = useRequest(Http, { manual: true })
    const { runAsync: getCamera } = useRequest(Http, { manual: true })

    const [ModelList, setModelList] = useState()
    const [VideoList, setVideoList] = useState()

    const { run: getClick } = useRequest(Http, {
        manual: true,
        onSuccess: ({ total, list }) => {
            if (total === 0) listFalse()
            else {
                setClickList(list)
                listTrue()
            }
        },
    })

    const ModifyClick = e => {
        e.styleName = Number(e.styleName)
        e.target = Number(e.target)
        if (e.url.indexOf('[') !== -1) e.url = JSON.parse(e.url)
        form.setFieldsValue(e)
        modalTrue()
    }
    const DeleteClick = e => {
        delClick({ url: `delClickEvents`, path: [e.uuid] }).then(() => {
            message.success('事件删除成功!')
            getClick({ url: `getClickEvents`, data: { ConstitutesUuid: ConstitutesUuid } })
        })
    }

    const CallBack = e => {
        message.success(e)
        getClick({ url: `getClickEvents`, data: { ConstitutesUuid: ConstitutesUuid } })
        modalFalse()
        form.resetFields()
    }

    useEffect(() => {
        getClick({ url: `getClickEvents`, data: { ConstitutesUuid: ConstitutesUuid } })
        getScene({ url: `getScenes`, data: { category: 1 } }).then(({ list }) => {
            let Model = []
            list.forEach(item => (Model = [...Model, { uuid: item.uuid, tableName: item.tableName }]))
            setModelList(Model)
        })
        getCamera({ url: `getCamera` }).then(({ list }) => {
            let Camera = []
            console.log(list)
            list.forEach(
                item =>
                    (Camera = [
                        ...Camera,
                        { uuid: item.uuid, tableName: `${item.tableName} - ${item.cameraPositionName}` },
                    ]),
            )
            setVideoList(Camera)
        })
    }, [ConstitutesUuid, getCamera, getClick, getScene])
    return (
        <div className="ModelBox animate__animated animate__slideInRight">
            <div className="ModelBoxClose" onClick={off}>
                <div>{tableName} 事件列表</div>
                <CloseOutlined />
            </div>
            {ListState ? (
                <div>
                    <List
                        dataSource={ClickList}
                        grid={{ gutter: 1, column: 1 }}
                        renderItem={item => (
                            <List.Item>
                                <Card
                                    extra={[
                                        <Button
                                            key={item.uuid + 1}
                                            type="link"
                                            icon={<EditOutlined />}
                                            onClick={() => ModifyClick(item)}
                                        />,
                                        <Popconfirm
                                            key={item.uuid + 2}
                                            title="是否要删除当前点击事件?"
                                            onConfirm={() => DeleteClick(item)}
                                            okText="删除"
                                            cancelText="取消"
                                        >
                                            <Button type="link" icon={<DeleteOutlined />} danger />
                                        </Popconfirm>,
                                    ]}
                                    type="inner"
                                    bordered={false}
                                    size="small"
                                    title={item.tableName}
                                >
                                    <div>样式 : {styleList[item.styleName]}</div>
                                    <div>类型 : {targetList[item.target]}</div>
                                    <div>状态 : {item.IsEnabled === 0 ? '关闭' : '启用'}</div>
                                </Card>
                            </List.Item>
                        )}
                    />

                    <div style={{ width: '100%', display: 'flex', justifyContent: 'center' }}>
                        <Button type="primary" onClick={modalTrue}>
                            新增点击事件
                        </Button>
                    </div>
                </div>
            ) : (
                <Result
                    status="404"
                    title="没有点击事件"
                    subTitle="抱歉, 当前对象还未配置点击事件!"
                    extra={
                        <Button type="primary" onClick={modalTrue}>
                            新增点击事件
                        </Button>
                    }
                />
            )}
            <Modal
                className="ModalPages"
                style={{ top: 200 }}
                width="50vw"
                open={modalState}
                onCancel={() => {
                    modalFalse()
                    form.resetFields()
                }}
                footer={null}
                destroyOnClose={true}
                maskClosable={false}
            >
                <div className="top">{'点击事件'}</div>
                <div className="center">
                    <Form
                        labelCol={{ span: 5 }}
                        wrapperCol={{ span: 16 }}
                        className="scenesBase"
                        form={form}
                        onFinish={data => {
                            data.constitutesUuid = ConstitutesUuid
                            data.category = Category
                            data.projectUuid = '0f196ef3-98f5-4e1a-a1e7-18f3d7fad4a2'
                            if (typeof data.url !== 'string') data.url = JSON.stringify(data.url)
                            if (data.uuid)
                                putClick({ url: `putClickEvents`, data, path: [data.uuid] }).then(() =>
                                    CallBack('事件添加成功'),
                                )
                            else posClick({ url: `posClickEvents`, data }).then(() => CallBack('事件修改成功'))
                        }}
                    >
                        <ClickFromModal form={form} ModelList={ModelList} VideoList={VideoList} />
                        <div style={{ width: '100%', display: 'flex', justifyContent: 'center' }}>
                            <Button style={{ width: 200 }} type="primary" onClick={() => form.submit()}>
                                提交
                            </Button>
                        </div>
                    </Form>
                </div>
            </Modal>
        </div>
    )
}
